package jinyilw.tools.net.file;

import jinyilw.common.log.LogTools;
import jinyilw.tools.net.NetTools;
import jinyilw.tools.net.dev.BaseClient;
import jinyilw.tools.net.dev.TCPClient;
import jinyilw.tools.net.dev.TCPServer;

import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;

public class FileTransferServer implements Runnable
{
	private final ServerSocketChannel serverChannel;
	private final Selector selector;
	private int clientNum;

	File receiveRootFolder = new File(System.getProperty("user.dir"));
	File sendRootFolder = receiveRootFolder;

	private volatile boolean threadRun = false;

	private TCPServer tcpServer;

	public FileTransferServer(int port) throws IOException
	{
		this(new InetSocketAddress(port));
	}

	public FileTransferServer(SocketAddress host) throws IOException
	{
		serverChannel = ServerSocketChannel.open();
		serverChannel.socket().bind(host);
		serverChannel.configureBlocking(false);
		selector = Selector.open();
		serverChannel.register(selector, SelectionKey.OP_ACCEPT);
	}

	public void update(long elapsedTime) throws IOException
	{
		selector.select();
		Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
		while (iterator.hasNext())
		{
			SelectionKey key = iterator.next();
			iterator.remove();
			if (key.isAcceptable())
			{
				SocketChannel socketChannel = serverChannel.accept();
				FileTransfer fileTransfer = new FileTransfer(this,
						socketChannel, selector);
				clientNum++;
				if (NetTools.debug)
					System.out.println("文件传输客户端连接成功... 连接数：" + clientNum);
			} else if (key.isReadable())
			{
				FileTransfer client = (FileTransfer) key.attachment();
				try
				{
					client.read();
				} catch (IOException e)
				{
					key.cancel();
					clientNum--;
					if (NetTools.debug)
						System.out.println("文件传输客户端断开连接... 连接数：" + clientNum);
				}
			}
		}
	}

	public void setTcpServer(TCPServer tcpServer)
	{
		this.tcpServer = tcpServer;
	}

	public TCPClient findTCPClient(int clientID)
	{
		if (tcpServer == null)
			return null;
		for (BaseClient client : tcpServer.getClients())
			if (client.getClientID() == clientID)
				return (TCPClient) client;
		return null;
	}

	public synchronized void stop()
	{
		threadRun = false;
		try
		{
			serverChannel.close();
		} catch (IOException e)
		{
			e.printStackTrace();
		}
	}

	protected void disconnect() throws IOException
	{
		serverChannel.close();
	}

	public String getDetail()
	{
		return serverChannel.socket().getLocalSocketAddress().toString();
	}

	public void setReceiveRootFolder(File folder)
	{
		receiveRootFolder = folder;
	}

	public void setSendRootFolder(File folder)
	{
		sendRootFolder = folder;
	}

	public synchronized void start()
	{
		if (threadRun)
			return;
		threadRun = true;
		new Thread(this).start();
	}

	@Override
	public void run()
	{
		if (NetTools.debug)
			LogTools.info("文件传输服务器启动成功...");
		while (threadRun)
			try
			{
				update(200);
			} catch (IOException e)
			{
				LogTools.debug("文件传输服务器停止运行!", e);
				threadRun = false;
				break;
			}
	}
}
